﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UObj = UnityEngine.Object;

public class LoadAwaiter : IAwaiter<LoadAwaiter, UObj>, IDisposable
{
    public bool IsCompleted { get; set; }

    public UObj Asset { get; private set; }

    public AssetBundle Bundle { get; private set; }

    public Type AssetType { get; private set; }

    public string AssetName { get; private set; }

    private AssetBundleRequest req;

    protected Action continuation = null;

    public LoadAwaiter(string assetName, AssetBundle ab, Type assetType = null)
    {
        AssetName = assetName;
        Bundle = ab;
        AssetType = assetType;
    }

    public LoadAwaiter GetAwaiter()
    {
        return this;
    }

    public UObj GetResult()
    {
        return Asset;
    }

    public void OnCompleted(Action continuation)
    {
        if (IsCompleted || Asset != null)
        {
            continuation?.Invoke();
            return;
        }
        this.continuation += continuation;
        if (req == null)
        {
            req = AssetType != null ? Bundle.LoadAssetAsync(AssetName, AssetType) : Bundle.LoadAssetAsync(AssetName);
            req.completed += OnFinish;
        }
    }

    private void OnFinish(AsyncOperation pp)
    {
        IsCompleted = true;
        Asset = req?.asset;
        req = null;
        continuation?.Invoke();
        continuation = null;
    }

    public void Dispose()
    {
        IsCompleted = true;
        Asset = null;
        req = null;
        continuation?.Invoke();
        continuation = null;
    }
}
